package net.oschina.victor.service;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import net.oschina.victor.entity.Organization;
import net.oschina.victor.repsotory.OrganizationRepsotory;
import net.oschina.victor.repsotory.UserRepsotory;

@Service
public class OrganizationServiceImpl implements OrganizationService {
	@Autowired
	private OrganizationRepsotory organizationRepsotory;
	@Autowired
	private UserRepsotory userRepsotory;

	@Override
	@Transactional
	public void deleteOrganization(Long organizationId) throws Exception {
		Organization organization = organizationRepsotory.findOne(organizationId);
		if (!organization.getAvailable()) { // 1、机构现在的状态
			throw new Exception("已经被删除组织机构,不需要在进行删除操作!");
		}
		if (!userRepsotory.findUsersByOrganizationId(organizationId.toString()).isEmpty()) { // 2、机构是否存在用户信息关联
			throw new Exception("组织机构下存在正常工作的用户，不能删除机构!");
		}
		// TODO :3、机构是否存在员工信息关联
		organization.setAvailable(false);
		organizationRepsotory.save(organization); // 4、将机构信息停用
	}

	@Override
	@Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
	public List<Organization> findAll() {
		// TODO:此处存在效率问题，需要优化
		List<Organization> list = new ArrayList<>();
		Sort sort = new Sort("priority");
		Iterator<Organization> it = organizationRepsotory.findAll(sort).iterator();
		while (it.hasNext()) {
			list.add(it.next());
		}
		return list;
	}

	@Override
	public Object findAllWithExclude(Organization excludeOraganization) {
		return organizationRepsotory.findAllWithExclude(excludeOraganization.getId().toString());
	}

	@Override
	@Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
	public Organization findById(Long organizationId) {
		return organizationRepsotory.findOne(organizationId);
	}

	@Override
	@Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
	public List<Organization> getChildren(Long id) {
		Specification<Organization> spec = new Specification<Organization>() {
			@Override
			public Predicate toPredicate(Root<Organization> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				return cb.and(cb.equal(root.get("parentId"), id), cb.isTrue(root.get("available"))); // 所有可用子机构信息
			}
		};
		return organizationRepsotory.findAll(spec);
	}

	@Override
	@Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
	public List<Organization> getChildrenAll(Long id) {
		Specification<Organization> spec = new Specification<Organization>() {
			@Override
			public Predicate toPredicate(Root<Organization> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				return cb.equal(root.get("parentId"), id); // 所有可用子机构信息
			}
		};
		return organizationRepsotory.findAll(spec);
	}

	@Override
	@Transactional
	public void move(Organization source, Organization target) {
		Organization _source = organizationRepsotory.findOne(source.getId());
		String oldParentIds = source.getParentIds();
		_source.setParentId(target.getId());
		_source.setParentIds(target.getParentIds() + target.getId() + ",");
		organizationRepsotory.save(_source); // 1、更新源实体的父级ID为目标实体的ID、父级Id助记串为新串
		organizationRepsotory.moveSourceDescendants(_source.getParentIds(), oldParentIds); // 2、更新所有原实体子孙机构的父级Id助记串为新串
	}

	@Override
	@Transactional
	public Organization saveOrganization(Organization organization) throws Exception {
		if (organization.getId() == null) {
			Organization parent = organizationRepsotory.findOne(organization.getParentId());
			if (parent == null) {
				throw new Exception("请选择要创建机构的隶属关系！");
			} else {
				organization.setParentIds((parent.getParentIds().isEmpty() ? "," : parent.getParentIds())
						+ organization.getParentId() + ",");
				organization.setLevel(parent.getLevel() + 1);
				// 此处应将触发器部署到数据库中
				// CREATE TRIGGER `organization.updateParentIds` BEFORE INSERT
				// ON `organization` FOR EACH ROW set new.parentIds=concat(
				// new.parentIds , new.id , ',')
			}
		}
		return organizationRepsotory.save(organization);
	}
}
